package com.bruce.practice.thread.calculate;

import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * @author luotuan
 * @Description
 * @create 2020-05-19 11:25
 **/
public class ExpensiveCache<A,V> implements Computable<A,V> {
    private final ConcurrentHashMap<A, Future<V>> cache = new ConcurrentHashMap<>();
    private final Computable<A,V> computable;

    public ExpensiveCache(Computable<A, V> computable) {
        this.computable = computable;
    }

    @Override
    public V compute(A arg) throws InterruptedException {
        while (true){
            Future<V> future = cache.get(arg);
            if(Objects.isNull(future)){
                System.out.println("缓存中不存在【"+arg+"】的计算结果");
                Callable<V> eval = () -> computable.compute(arg);
                FutureTask<V> futureTask = new FutureTask<>(eval);
                future = cache.putIfAbsent(arg,futureTask);
                if(Objects.isNull(future)){
                    future = futureTask;
                    futureTask.run();
                }
            }else{
                System.out.println("缓存中获取到了参数【"+arg+"】的计算结果");
            }
            try {
                V result = future.get();
                System.out.println("参数【"+arg+"】获取到的计算结果："+result);
                return result;
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}
